<template>
  <div ref="canvas"></div>
</template>

<script lang="ts" setup>
import * as THREE from 'three';
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { ref, onMounted } from "vue";
// @ts-ignore
import testPng from '@/assets/test.png'

// 画布
const canvas = ref<any>('');
// 场景
const scene = new THREE.Scene();
// 几何体
const plane = new THREE.PlaneGeometry(2000, 2000);
// 纹理贴图加载器
const textureLoader = new THREE.TextureLoader();
// 纹理贴图
const texture = textureLoader.load(testPng);
// 设置阵列模式
// 设置.wrapS也就是U方向，纹理映射模式(包裹模式) - 对应 offset.x 偏移
texture.wrapS = THREE.RepeatWrapping;
// 设置.wrapT也就是V方向，纹理映射模式 - 对应 offset.y 偏移
texture.wrapT = THREE.RepeatWrapping;
// uv两个方向纹理重复数量
texture.repeat.set(10, 10);
// 纹理U方向偏移
// texture.offset.x += 0.5;
// 纹理V方向偏移
// texture.offset.y +=0.5;
// 材质
const material = new THREE.MeshLambertMaterial({
  map: texture,
  side: THREE.DoubleSide,
});
// 网格模型Mesh
const mesh = new THREE.Mesh(plane, material);
scene.add(mesh);
// 旋转矩形平面 - 矩形平面默认是在XOY平面上，如果想要让矩形平面在XOZ平面上，就需要手动旋转
// ThreeJs 用的是 右手三维坐标系: 即 X 轴正方向向右，Y 轴正方向向上，Z 轴由屏幕从里向外。
//   Y
// Z   X
// 与之相对的则是左手三维坐标系: X 轴正方向向右，Y 轴正方向向上，Z 轴由屏幕从外向里
//   Y   Z
//     X
mesh.rotateX(-Math.PI / 2);
// 环境光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.8);
scene.add(ambientLight);
// 相机
const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 5000);
camera.position.set(1300, 500, 1300);
camera.lookAt(0, 0, 0);
// 渲染器
const renderer = new THREE.WebGLRenderer({
  antialias: true,
});
renderer.setClearColor(0xffffff);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// 渲染函数
const render = () => {
  // 纹理贴图 - 动画效果
  texture.offset.x += 0.005;
  texture.offset.y += 0.005;
  // 网格模型 mesh 转动
  mesh.rotation.x += 0.005;
  mesh.rotation.y += 0.005;

  renderer.render(scene, camera);
  requestAnimationFrame(render);
}
// 相机控件
const orbitControl = new OrbitControls(camera, renderer.domElement);
orbitControl.update();

onMounted(() => {
  canvas.value.appendChild(renderer.domElement);
  render();
});
</script>
